﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ProModel.ApplicationFramework.Silverlight
{
    #region WindowHelpers Class

    /// <summary>
    /// General methods for use with Silverlight development.
    /// </summary>
    public class WindowHelpers
    {
        #region Method Declarations

        #region Size

        /// <summary>
        /// Checks a FrameworkElement for a "usable" width. If width/height are NAN
        /// actualwidth/actualheight will be used.
        /// </summary>
        /// <returns>Size of the specified control.</returns>
        public static Size GetFrameworkElementSize(FrameworkElement frameworkElement)
        {
            Size retSz = new Size();
            retSz.Width = double.IsNaN(frameworkElement.Width) ? frameworkElement.ActualWidth : frameworkElement.Width;
            retSz.Height = double.IsNaN(frameworkElement.Height) ? frameworkElement.ActualHeight : frameworkElement.Height;
            return retSz;
        }

        /// <summary>
        /// Checks a Control for a "usable" width. If width/height are NAN
        /// actualwidth/actualheight will be used.
        /// </summary>
        public static Size GetControlSize(Control control)
        {
            Size retSz = new Size();
            retSz.Width = double.IsNaN(control.Width) ? control.ActualWidth : control.Width;
            retSz.Height = double.IsNaN(control.Height) ? control.ActualHeight : control.Height;
            return retSz;
        }

        /// <summary>
        /// Checks a Panel for a "usable" width. If width/height are NAN
        /// actualwidth/actualheight will be used.
        /// </summary>
        public static Size GetPanelSize(Panel panel)
        {
            Size retSz = new Size();
            retSz.Width = double.IsNaN(panel.Width) ? panel.ActualWidth : panel.Width;
            retSz.Height = double.IsNaN(panel.Height) ? panel.ActualHeight : panel.Height;
            return retSz;
        }

        /// <summary>
        /// Returns the size including margins
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static Size GetFrameworkElementDisplaySize(FrameworkElement element)
        {
            Size retSz = new Size();
            retSz.Width = GetFrameworkElementSize(element).Width + element.Margin.Left + element.Margin.Right;
            retSz.Height = GetFrameworkElementSize(element).Height + element.Margin.Top + element.Margin.Bottom;
            return retSz;
        }

        #endregion

        #region Containers

        /// <summary>
        /// 	<para>Recurses up the window chain until the root level Panel control (the
        ///     LayoutRoot hopefully) and return that Panel instance.</para>
        /// </summary>
        /// <example>
        /// 	<para><font color="#F95100" size="2"><font color="#F95100" size="2">Panel</font></font>
        /// 		<font size="2">rootVisual =</font>
        /// 		<font color="#F95100" size="2"><font color="#F95100" size="2">WindowHelpers</font></font><font size="2">.GetContainingPanel(this</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">as</font></font>
        /// 		<font color="#F95100" size="2"><font color="#F95100" size="2">FrameworkElement</font></font><font size="2">);</font></para>
        /// 	<para><font color="blue" size="2"><font color="blue" size="2">if</font></font>
        /// 		<font size="2">(rootVisual !=</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">null</font></font><font size="2">)</font></para>
        /// 	<para><font size="2">{</font></para>
        /// 	<para><font size="2">rootVisual.Children.Insert(</font><font color="gray" size="2"><font color="gray" size="2">0</font></font><font size="2">,
        ///     _popup);</font></para>
        /// 	<para><font size="2">_popup.IsOpen =</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">true</font></font><font size="2">;</font></para>
        /// 	<para><font size="2">}</font></para>
        /// </example>
        /// <returns>Returns the top-level containing Panel.</returns>
        /// <remarks>This method will return the host page's LayoutRoot instance.</remarks>
        /// <param name="element">
        /// The <font color="#F95100" size="2"><font color="#F95100" size="2">FrameworkElement <font color="black">whose containing Panel is to be
        /// found.</font></font></font>
        /// </param>
        public static Panel GetContainingPanel(FrameworkElement element)
        {
            Panel retPanel = element as Panel; // nulled unless it's a Panel

            if (element != null && element.Parent != null)
            {
                Panel basePanel = GetContainingPanel(element.Parent as FrameworkElement);

                if (basePanel != null)
                {
                    retPanel = basePanel;
                }
            }

            return retPanel;
        }

        #endregion

        #endregion
    }

    #endregion
}
